#***************************************************************************
#*                                                                         *
#*   Copyright (c) 2018 Yorik van Havre <yorik@uncreated.net>              *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENCE text file.                                 *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Library General Public License for more details.                  *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with this program; if not, write to the Free Software   *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

from __future__ import print_function

"""This is the tutorial of the BIM workbench"""


import os
import FreeCAD
from BimTranslateUtils import *


html = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }</style></head><body>inserthere</body></html>"""

URL = "https://www.freecadweb.org/wiki/BIM_ingame_tutorial"
TESTINTERVAL = 1000 # interval between tests


class BIM_Tutorial:


    def GetResources(self):

        return {'Pixmap'  : os.path.join(os.path.dirname(__file__),"icons","BIM_Tutorial.svg"),
                'MenuText': QT_TRANSLATE_NOOP("BIM_Tutorial", "BIM Tutorial"),
                'ToolTip' : QT_TRANSLATE_NOOP("BIM_Tutorial", "Starts or continues the BIM in-game tutorial")}

    def Activated(self):

        import FreeCADGui
        from PySide import QtCore,QtGui
        # find existing tutorial
        m = FreeCADGui.getMainWindow()
        self.dock = m.findChild(QtGui.QDockWidget,"BIMTutorial")

        if not self.dock:

            # set the tutorial dialog up
            self.form = FreeCADGui.PySideUic.loadUi(os.path.join(os.path.dirname(__file__),"dialogTutorial.ui"))
            self.form.setObjectName("BIMTutorial")
            self.form.progressBar.setValue(0)
            self.form.labelGoal1.setText("")
            self.form.labelGoal2.setText("")
            self.form.labelIcon1.setText("")
            self.form.labelIcon2.setText("")
            self.form.buttonPrevious.setEnabled(False)
            self.form.buttonNext.setEnabled(False)
            self.form.buttonPrevious.clicked.connect(self.previous)
            self.form.buttonNext.clicked.connect(self.next)
            self.form.labelTasks.hide()
            self.form.textEdit.setOpenExternalLinks(True)

            self.dock = QtGui.QDockWidget()
            self.dock.setWidget(self.form)

            m.addDockWidget(QtCore.Qt.RightDockWidgetArea,self.dock)

            # load icons
            self.pixyes = QtGui.QPixmap(":/icons/button_valid.svg").scaled(16,16)
            self.pixno = QtGui.QPixmap(":/icons/button_right.svg").scaled(16,16)
            self.pixempty = QtGui.QPixmap()

            # fire the loading after displaying the widget
            from DraftGui import todo
            #self.load()
            #todo.delay(self.load,None)
            QtCore.QTimer.singleShot(1000,self.load)

    def load(self,arg=None):

        import re,sys,codecs
        if sys.version_info.major < 3:
            import urllib2
        else:
            import urllib.request as urllib2

        # initial loading

        if not hasattr(self,"form") or not self.form or not hasattr(self,"dock"):
            return

        # load tutorial from wiki
        offlineloc = os.path.join(FreeCAD.getUserAppDataDir(),"BIM","Tutorial","Tutorial.html")
        try:
            u = urllib2.urlopen(URL)
            html = u.read()
            if sys.version_info.major >= 3:
                html = html.decode("utf8")
            html = html.replace("\n"," ")
            html = html.replace("\"/wiki/","\"https://www.freecadweb.org/wiki/")
            html = re.sub("<div id=\"toc\".*?</ul> </div>","",html) # remove table of contents
            u.close()
        except:
            # unable to load tutorial. Look for offline version
            if os.path.exists(offlineloc):
                f = open(offlineloc)
                html = f.read()
                f.close()
            else:
                FreeCAD.Console.PrintError(translate("BIM","Unable to access the tutorial. Verify that you are online (This is needed only once).")+"\n")
                return
        else:
            if not os.path.exists(os.path.dirname(offlineloc)):
                os.makedirs(os.path.dirname(offlineloc))
            f = codecs.open(offlineloc,"w","utf-8")
            f.write(html)
            f.close()
    
        # setup title and progress bar
        self.steps = len(re.findall("infotext",html))-1

        # setup description texts and goals
        self.descriptions = [""]+re.findall("<p><br /> </p><p><br /> </p> (.*?)<p><b>Tutorial step",html)
        self.goal1 = re.findall("goal1\">(.*?)</div",html)
        self.goal2 = re.findall("goal2\">(.*?)</div",html)
        self.test1 = re.findall("test1\".*?>(.*?)</div",html)
        self.test2 = re.findall("test2\".*?>(.*?)</div",html)
        
        # fix mediawiki encodes
        self.test1 = [t.replace("&lt;","<").replace("&gt;",">") for t in self.test1]
        self.test2 = [t.replace("&lt;","<").replace("&gt;",">") for t in self.test2]
        
        # download images (QTextEdit cannot load online images)
        self.form.textEdit.setHtml(html.replace("inserthere",translate("BIM","Downloading images...")))
        nd = []
        for descr in self.descriptions:
            imagepaths = re.findall("<img.*?src=\"(.*?)\"",descr)
            if imagepaths:
                store = os.path.join(FreeCAD.getUserAppDataDir(),"BIM","Tutorial")
                if not os.path.exists(store):
                    os.makedirs(store)
                for path in imagepaths:
                    name = re.findall("[\\w.-]+\\.(?i)(?:jpg|png|gif|bmp)",path)
                    if name:
                        name = name[-1]
                        storename = os.path.join(store,name)
                        if not os.path.exists(storename):
                            if path.startswith("/images"):
                                # relative path
                                fullpath = "https://www.freecadweb.org/wiki"+path
                            else:
                                fullpath = path
                            u = urllib2.urlopen(fullpath)
                            imagedata = u.read()
                            f = open(storename,"wb")
                            f.write(imagedata)
                            f.close()
                            u.close()
                        #descr = descr.replace(path,"file://"+storename.replace("\\","/"))
                        # fix for windows - seems to work everywhere else too...
                        descr = descr.replace(path,"file:///"+storename.replace("\\","/"))
                    else:
                        print("unparsable image path:",path)
            nd.append(descr)
        self.descriptions = nd
        
        # check where we are
        self.step = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/BIM").GetInt("CurrentTutorialStep",0)
        if self.step:
            self.update()
        else:
            self.next()

    def next(self):

        self.step += 1
        self.update()

    def previous(self):

        self.step -= 1
        self.update()


    def update(self):

        from PySide import QtCore,QtGui

        if not hasattr(self,"form") or not self.form or not hasattr(self,"dock"):
            return

        # stay within bounds!
        if self.step > self.steps:
            self.step = self.steps
        elif self.step < 1:
            self.step = 1

        t = self.descriptions[self.step]
        
        #print(t)
        
        # set contents
        self.form.textEdit.setHtml(html.replace("inserthere",t))
        self.form.labelGoal1.setText(self.goal1[self.step])
        if self.goal1[self.step]:
            self.form.labelIcon1.setPixmap(self.pixno)
        else:
            self.form.labelIcon1.setPixmap(self.pixempty)
        self.form.labelGoal2.setText(self.goal2[self.step])
        if self.goal2[self.step]:
            self.form.labelIcon2.setPixmap(self.pixno)
        else:
            self.form.labelIcon2.setPixmap(self.pixempty)
        if self.goal1[self.step] or self.goal2[self.step]:
            self.form.labelTasks.show()
        else:
            self.form.labelTasks.hide()
        self.dock.setWindowTitle(translate("BIM","BIM Tutorial - step")+" "+str(self.step)+" / "+str(self.steps))
        self.form.progressBar.setValue(int((float(self.step)/self.steps)*100))
        
        # save the current step
        FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/BIM").SetInt("CurrentTutorialStep",self.step)

        if self.steps > self.step:
            self.form.buttonNext.setEnabled(True)
        else:
            self.form.buttonNext.setEnabled(False)
        if self.step == 1:
            self.form.buttonPrevious.setEnabled(False)
        else:
            self.form.buttonPrevious.setEnabled(True)

        # launch test watcher
        self.done1 = False
        self.done2 = False
        if self.test1[self.step] or self.test2[self.step]:
            QtCore.QTimer.singleShot(TESTINTERVAL, self.checkGoals)

    def checkGoals(self):

        from PySide import QtCore,QtGui

        if not hasattr(self,"form"):
            return

        if self.goal1[self.step]:
            if self.test1[self.step]:
                if not self.done1:
                    try:
                        result = eval(self.test1[self.step])
                    except:
                        print ("BIM Tutorial: unable to eval: "+self.test1[self.step])
                        result = False
                        self.done1 = True
                    if result:
                        self.form.labelIcon1.setPixmap(self.pixyes)
                        self.done1 = True

        if self.goal2[self.step]:
            if self.test2[self.step]:
                if not self.done2:
                    try:
                        result = eval(self.test2[self.step])
                    except:
                        print ("BIM Tutorial: unable to eval: "+self.test2[self.step])
                        result = False
                        self.done2 = True
                    if result:
                        self.form.labelIcon2.setPixmap(self.pixyes)
                        self.done2 = True

        if (self.test1[self.step] or self.test2[self.step]) and ((not self.done1) or (not self.done2)):
            QtCore.QTimer.singleShot(TESTINTERVAL, self.checkGoals)
